package com.mzj.saas.mservice.token.service;

import com.alibaba.fastjson.JSON;
import com.mzj.saas.commons.*;
import com.mzj.saas.commons.vo.redis.TokenRedisVo;
import com.mzj.saas.mservice.token.vo.TokenVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.concurrent.TimeUnit;

@Service
public class TokenService {
    private Logger LOG = LoggerFactory.getLogger(TokenService.class);
    @Value(value = "${token.auth.secretKey}")
    private String tokenAuthSecretKey;// 秘钥
    @Value(value = "${redis.token.expire.time}")
    private Integer redisTokenExpireTime;// 过期时间

    @Autowired
    @Qualifier("stringRedisTemplate")
    public StringRedisTemplate redisTemplate;

    @SuppressWarnings("static-access")
    public ResultBean<String> authToken(TokenVo vo) {
        LOG.info("TokenService authToken parmas = {}", vo.toString());
        ResultBean<String> resultBean = new ResultBean<>();
        try {
            resultBean.setCode(StatusCode.SUCCESS_CODE_10000.getErrorCode());
            resultBean.setMsg(StatusCode.SUCCESS_CODE_10000.getErrorMsg());

            if (StringUtils.isBlank(vo.getCode()) || StringUtils.isBlank(vo.getEncryptCode())
                    || StringUtils.isBlank(vo.getIvParameter())) {
                resultBean.setCode(StatusCode.ERROR_CODE_10004.getErrorCode());
                resultBean.setMsg(StatusCode.ERROR_CODE_10004.getErrorMsg());
                return resultBean;
            }

            AESUtil aesUtil = AESUtil.getInstance(tokenAuthSecretKey);
            String decryptCode = aesUtil.aesDecrypt(vo.getEncryptCode(), vo.getIvParameter()); // 校验加密字符串是否合法
            if (!StringUtils.equals(vo.getCode(), decryptCode)) {
                resultBean.setMsg(StatusCode.ERROR_CODE_10003.getErrorMsg());
                resultBean.setCode(StatusCode.ERROR_CODE_10003.getErrorCode());
                return resultBean;
            }

            String md5Code = MD5Utils.MD5Encode(vo.getEncryptCode(), "UTF-8"); // 进行一次md5算法，去除特殊符号
            String tokenKeyValue = Constant.LOGIN_TOKEN + ":" + md5Code;
            if (redisTemplate.opsForValue().get(tokenKeyValue) == null) { // 如果为空的时候,插入redis数据库
                redisTemplate.opsForValue().set(tokenKeyValue, tokenKeyValue, redisTokenExpireTime, TimeUnit.MINUTES);
                LOG.info("TokenService authToken redis save success, key = {}, value = {}", tokenKeyValue,
                        tokenKeyValue);
            }

            resultBean.setResultData(redisTemplate.opsForValue().get(tokenKeyValue));
            return resultBean;

        } catch (Exception e) {
            LOG.error("TokenService authToken Exception = {}", e);
            resultBean.setCode(StatusCode.ERROR_CODE_30001.getErrorCode());
            resultBean.setMsg(StatusCode.ERROR_CODE_30001.getErrorMsg());
            return resultBean;
        }

    }

    /**
     * 生成token
     *
     * @param name
     * @param password
     * @param id
     * @param mobile
     * @param flag
     * @param masterStatus
     * @param enterpriseId
     * @param loginType
     * @return
     * @author shun
     * @date 2021年6月24日
     */
    public String authToken(String name, String password, String id, String mobile, Integer flag, Long masterStatus,
                            Long enterpriseId, Integer loginType, String enterpriseUserId) {
        LOG.info("TokenService authToken name={}, password={}, userId={}, mobile={}, loginType={}, enterpriseUserId={}",
                name, password, id, mobile, loginType, enterpriseUserId);
        try {
            TokenRedisVo vo = new TokenRedisVo();
            vo.setCreateTime(DateUtils.format(new Date(), DateUtils.FORMAT_14));
            vo.setLoginName(mobile);
            vo.setPassword(password);
            vo.setId(id);
            vo.setName(name);
            vo.setFlag(flag);
            vo.setMasterStatus(masterStatus);
            vo.setEnterpriseId(enterpriseId);
            vo.setLoginType(loginType);
            vo.setEnterpriseUserId(enterpriseUserId);
            vo.setPhone(mobile);
            String tokenKey = vo.getLoginName() + vo.getPassword() + vo.getCreateTime() + vo.getName() + vo.getId()
                    + vo.getFlag() + vo.getMasterStatus() + vo.getEnterpriseId() + vo.getPhone();
            String md5tokenKey = Constant.LOGIN_TOKEN + ":" + MD5Utils.MD5Encode(tokenKey, "UTF-8"); // 进行一次md5算法，去除特殊符号
            redisTemplate.opsForValue().set(md5tokenKey, JSON.toJSONString(vo), redisTokenExpireTime, TimeUnit.MINUTES);

            // 缓存用户与token关系
            if (enterpriseId != null) {
                redisTemplate.opsForValue().set(Constant.LOGIN_USER + ":" + id + ":" + flag, md5tokenKey);
            }
            return md5tokenKey;

        } catch (Exception e) {
            LOG.error("TokenService authToken Exception = {}", e);

        }
        return null;
    }

    /**
     * 生成token
     *
     * @param name
     * @param password
     * @param id
     * @param mobile
     * @param flag
     * @param masterStatus
     * @param enterpriseId
     * @param loginType
     * @return
     * @author shun
     * @date 2021年6月24日
     */
    public String authToken(String name, String password, String id, String mobile, Integer flag, Long masterStatus,
                            Long enterpriseId, Integer loginType, String enterpriseUserId, Integer certificationStatus) {
        LOG.info("TokenService authToken name={}, password={}, userId={}, mobile={}, loginType={}, enterpriseUserId={},certificationStatus={}",
                name, password, id, mobile, loginType, enterpriseUserId, certificationStatus);
        try {
            TokenRedisVo vo = new TokenRedisVo();
            vo.setCreateTime(DateUtils.format(new Date(), DateUtils.FORMAT_14));
            vo.setLoginName(mobile);
            vo.setPassword(password);
            vo.setId(id);
            vo.setName(name);
            vo.setFlag(flag);
            vo.setMasterStatus(masterStatus);
            vo.setEnterpriseId(enterpriseId);
            vo.setLoginType(loginType);
            vo.setEnterpriseUserId(enterpriseUserId);
            vo.setCertificationStatus(certificationStatus);
            vo.setPhone(mobile);
            LOG.info("vo = " + JSON.toJSONString(vo));
            String tokenKey = vo.getLoginName() + vo.getPassword() + vo.getCreateTime() + vo.getName() + vo.getId()
                    + vo.getFlag() + vo.getMasterStatus() + vo.getEnterpriseId() + vo.getCertificationStatus() + vo.getPhone();
            String md5tokenKey = Constant.LOGIN_TOKEN + ":" + MD5Utils.MD5Encode(tokenKey, "UTF-8"); // 进行一次md5算法，去除特殊符号
            redisTemplate.opsForValue().set(md5tokenKey, JSON.toJSONString(vo), redisTokenExpireTime, TimeUnit.MINUTES);
            // 缓存用户与token关系
            if (enterpriseId != null) {
                redisTemplate.opsForValue().set(Constant.LOGIN_USER + ":" + id + ":" + flag, md5tokenKey);
            }
            return md5tokenKey;

        } catch (Exception e) {
            LOG.error("TokenService authToken Exception = {}", e);

        }
        return null;
    }

    /**
     * 生成小程序token
     *
     * @param name
     * @param password
     * @param id
     * @param mobile
     * @param flag
     * @param masterStatus
     * @param enterpriseId
     * @param loginType
     * @return
     * @author shun
     * @date 2021年6月24日
     */
    public String authTokenLet(String name, String password, String id, String mobile, Integer flag, Long masterStatus,
                               Long enterpriseId, Integer loginType, String enterpriseUserId, Integer certificationStatus) {
        LOG.info("TokenService authToken name={}, password={}, userId={}, mobile={}, loginType={}, enterpriseUserId={}",
                name, password, id, mobile, loginType, enterpriseUserId);
        try {
            TokenRedisVo vo = new TokenRedisVo();
            vo.setCreateTime(DateUtils.format(new Date(), DateUtils.FORMAT_14));
            vo.setLoginName(mobile);
            vo.setPassword(password);
            vo.setId(id);
            vo.setName(name);
            vo.setFlag(flag);
            vo.setMasterStatus(masterStatus);
            vo.setEnterpriseId(enterpriseId);
            vo.setLoginType(loginType);
            vo.setEnterpriseUserId(enterpriseUserId);
            vo.setCertificationStatus(certificationStatus);
            String tokenKey = vo.getLoginName() + vo.getPassword() + vo.getCreateTime() + vo.getName() + vo.getId()
                    + vo.getFlag() + vo.getMasterStatus() + vo.getEnterpriseId() + vo.getCertificationStatus();
            String md5tokenKey = Constant.LOGIN_TOKEN + ":" + MD5Utils.MD5Encode(tokenKey, "UTF-8"); // 进行一次md5算法，去除特殊符号
            redisTemplate.opsForValue().set(md5tokenKey, JSON.toJSONString(vo), redisTokenExpireTime, TimeUnit.MINUTES);

            // 缓存用户与token关系
            if (enterpriseId != null) {
                redisTemplate.opsForValue().set(Constant.LOGIN_USER + ":" + id + ":" + flag, md5tokenKey);
            }
            return md5tokenKey;

        } catch (Exception e) {
            LOG.error("TokenService authToken Exception = {}", e);

        }
        return null;
    }

    /**
     * 更新缓存token
     *
     * @param accessToken
     * @param vo
     * @author shun
     * @date 2021年6月24日
     */
    public void updateAuthTokenInfo(String accessToken, TokenRedisVo vo) {
        redisTemplate.opsForValue().set(accessToken, JSON.toJSONString(vo), redisTokenExpireTime, TimeUnit.MINUTES);
    }
}

